//
//  QSKeyedArchiverTool.m
//  ZengLongSeSha
//
//  Created by apple on 2017/8/31.
//  Copyright © 2017年 Song. All rights reserved.
//

#import "QSKeyedArchiverTool.h"
#import <objc/runtime.h>

@implementation QSKeyedArchiverTool
/**
 *  序列化
 */
+ (void)archiveModelData:(id)model toFile:(NSString *)fileName
{
    // 创建文件路径
    NSString *filePath = [kDocumentDirectory stringByAppendingPathComponent:fileName];
    
    // 创建data对象
    NSMutableData *data = [[NSMutableData alloc] init];
    // 创建归档工具
    NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
    
    //获取属性
    NSArray *properties = [[self alloc] getPropertiesFromClass:[model class]];
    
    // 归档数据, 遍历所有属性通过KVC赋值
    for (NSString *property in properties)
    {
        id obj = [model valueForKey:property];
        [archiver encodeObject:obj forKey:property];
    }
    
    // 结束归档
    [archiver finishEncoding];
    // 将数据写入文件中
    [data writeToFile:filePath atomically:YES];
}

/**
 *  反序列化
 */
+ (id)unarchiveModelDataFromFile:(NSString *)fileName withModelClass:(__unsafe_unretained Class)modelClass
{
    // 获取文件路径
    NSMutableData *datR = [[NSMutableData alloc] initWithContentsOfFile:[kDocumentDirectory stringByAppendingPathComponent:fileName]];
    // 创建反归档工具
    NSKeyedUnarchiver *unchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:datR];
    
    //获取属性
    NSArray *properties = [[self alloc] getPropertiesFromClass:modelClass];

    id returnObj = [[modelClass alloc] init];
    // 反归档数据, 遍历所有属性通过KVC赋值
    for (NSString *property in properties)
    {
        id obj = [unchiver decodeObjectForKey:property];
        if (obj) {
            [returnObj setValue:obj forKey:property];
        }
    }
    
    // 反归档结束
    [unchiver finishDecoding];
    return returnObj;
}

/**
 *  获取类中的属性名
 *
 *  @param cls 数据类
 *  @return 属性名数组
 */
- (NSArray *)getPropertiesFromClass:(Class)cls
{
    // 保存所有的属性名字
    NSMutableArray *array = [NSMutableArray array];
    
    // 属性个数
    unsigned int outCount;
    // 获取所有的属性    copy,retain,create都需要手动释放
    objc_property_t *properties = class_copyPropertyList(cls, &outCount);
    for (int i = 0; i < outCount; i++)
    {
        // 每个属性的结构体
        objc_property_t property = properties[i];
        // 获取属性名字
        const char *name = property_getName(property);
        [array addObject:[NSString stringWithUTF8String:name]];
    }
    
    // 释放资源
    free(properties);
    return array;
}
@end
